package rdbms.util;

import common.util.RangeSplits;
import org.apache.commons.lang3.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

public final class RdbmsRangeSplitWrap
{

    public static List<String> splitAndWrap(String left, String right, int expectSliceNumber,
                                            String columnName, String quote)
    {
        String[] tempResult = RangeSplits.doAsciiStringSplit(left, right, expectSliceNumber);
        return RdbmsRangeSplitWrap.wrapRange(tempResult, columnName, quote);
    }

    // warn: do not use this method long->BigInteger
    public static List<String> splitAndWrap(long left, long right, int expectSliceNumber, String columnName)
    {
        long[] tempResult = RangeSplits.doLongSplit(left, right, expectSliceNumber);
        return RdbmsRangeSplitWrap.wrapRange(tempResult, columnName);
    }

    public static List<String> splitAndWrap(BigInteger left, BigInteger right, int expectSliceNumber, String columnName)
    {
        BigInteger[] tempResult = RangeSplits.doBigIntegerSplit(left, right, expectSliceNumber);
        return RdbmsRangeSplitWrap.wrapRange(tempResult, columnName);
    }

    public static List<String> wrapRange(long[] rangeResult, String columnName)
    {
        String[] rangeStr = new String[rangeResult.length];
        for (int i = 0, len = rangeResult.length; i < len; i++)
        {
            rangeStr[i] = String.valueOf(rangeResult[i]);
        }
        return wrapRange(rangeStr, columnName, "");
    }

    public static List<String> wrapRange(BigInteger[] rangeResult, String columnName)
    {
        String[] rangeStr = new String[rangeResult.length];
        for (int i = 0, len = rangeResult.length; i < len; i++)
        {
            rangeStr[i] = rangeResult[i].toString();
        }
        return wrapRange(rangeStr, columnName, "");
    }

    public static List<String> wrapRange(String[] rangeResult, String columnName,
                                         String quote)
    {
        if (null == rangeResult || rangeResult.length < 2)
        {
            throw new IllegalArgumentException(String.format(
                    "Parameter rangeResult can not be null and its length can not <2. detail:rangeResult=[%s].",
                    StringUtils.join(rangeResult, ",")));
        }

        List<String> result = new ArrayList<String>();

        //TODO  change to  stringbuilder.append(..)
        if (2 == rangeResult.length)
        {
            result.add(String.format(" (%s%s%s <= %s AND %s <= %s%s%s) ", quote, quoteConstantValue(rangeResult[0]),
                    quote, columnName, columnName, quote, quoteConstantValue(rangeResult[1]), quote));
            return result;
        } else
        {
            for (int i = 0, len = rangeResult.length - 2; i < len; i++)
            {
                result.add(String.format(" (%s%s%s <= %s AND %s < %s%s%s) ", quote, quoteConstantValue(rangeResult[i]),
                        quote, columnName, columnName, quote, quoteConstantValue(rangeResult[i + 1]), quote));
            }

            result.add(String.format(" (%s%s%s <= %s AND %s <= %s%s%s) ", quote, quoteConstantValue(rangeResult[rangeResult.length - 2]),
                    quote, columnName, columnName, quote, quoteConstantValue(rangeResult[rangeResult.length - 1]), quote));
            return result;
        }
    }


    private static String quoteConstantValue(String aString)
    {

        return aString.replace("'", "''").replace("\\", "\\\\");
    }
}
